#ifndef RP2SKCONTROLLER_H
#define RP2SKCONTROLLER_H

#include "Rp2Controller.h"
#include "Rp2FloatArray.h"
#include "Rp2QuaternionArray.h"
#include "Rp2Vector3Array.h"
#include "Rp2SkinningEffect.h"

namespace Rp2
{

class SKController : public Controller
{
	RP2_DECLARE_RTTI;
	RP2_DECLARE_NAME_ID;

public:
	SKController();
	virtual ~SKController();
	
	std::vector<int> FrameQuantity;

	// keyframe times
	FloatArrayPtr Times;

	// keyframe transforms
	Vector3fArrayPtr TranslationData;
	QuaternionfArrayPtr RotationData;
	FloatArrayPtr ScaleData;
	
	// member access
	void SetTranslate(int iBoneIndex, int iFrameIndex, Vector3f& rkData);
	void SetRotate(int iBoneIndex, int iFrameIndex, Quaternionf& rkData);
	void SetScale(int iBoneIndex, int iFrameIndex, float fData);

	virtual bool Update(double dAppTime);

protected:
	static void GetKeyInfo(float fCtrlTime, int iQuantity, float* afTime,
		int& riLastIndex, float& rfNormTime, int& ri0, int& ri1);

	Vector3f GetTranslate(int iBoneIndex, float fNormTime, int i0, int i1);
	Matrix4f GetRotate(int iBoneIndex, float fNormTime, int i0, int i1);
	float GetScale(int iBoneIndex, float fNormTime, int i0, int i1);

	Matrix4f GetTransform(int i, float fNormTime, int i0, int i1);
	void UpdateRelTransform(Bone* pkBone, const Matrix4f& rkMT, const Matrix4f& rkOrient);
	void UpdateLocalTransform(Bone* pkBone, const Vector4f& rkT, const Matrix4f& rkOrient,
		const Matrix4f& rkMRot, const Matrix4f& rkG, float fNormTime, int i0, int i1, bool bRootBone);

    // Cached indices for the last found pair of keys used for interpolation.
    // For a sequence of times, this guarantees an O(1) lookup.
    int m_iTLastIndex;
    int m_iRLastIndex;
    int m_iSLastIndex;
};

typedef Pointer<SKController> SKControllerPtr;

}

#endif
